#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
WMS Sample 服务配置管理工具
提供图形界面管理Windows服务和系统配置
"""

import os
import sys
import json
import tkinter as tk
from tkinter import ttk, messagebox, filedialog
import threading
from pathlib import Path

# 添加项目根目录到Python路径
current_dir = Path(__file__).parent.parent
sys.path.insert(0, str(current_dir))

from src.core.service_manager import ServiceManager
from src.core.path_manager import path_manager


class ServiceConfigManager:
    """服务配置管理器GUI"""
    
    def __init__(self):
        self.root = tk.Tk()
        self.root.title("WMS Sample 服务配置管理工具")
        self.root.geometry("800x600")
        self.root.resizable(True, True)
        
        # 服务管理器
        self.service_manager = ServiceManager(
            service_name="WMSSampleService",
            display_name="WMS Sample 料位管理服务",
            description="WMS Sample 料位管理系统后台服务"
        )
        
        # 配置文件路径
        self.config_file = path_manager.get_config_file("config.json")
        self.default_config = {
            "api_host": "127.0.0.1",
            "api_port": 58501,
            "cors_origins": ["*"],
            "database_path": str(path_manager.get_database_file()),
            "log_level": "INFO",
            "service_startup_type": "auto"
        }
        
        # 加载配置
        self.config = self.load_config()
        
        # 检测部署环境
        self.deployment_mode = path_manager.deployment_mode
        
        # 创建界面
        self.create_widgets()
        
        # 更新服务状态
        self.update_service_status()
    
    def load_config(self):
        """加载配置文件"""
        try:
            if self.config_file.exists():
                with open(self.config_file, 'r', encoding='utf-8') as f:
                    config = json.load(f)
                # 合并默认配置
                for key, value in self.default_config.items():
                    if key not in config:
                        config[key] = value
                return config
            else:
                return self.default_config.copy()
        except Exception as e:
            messagebox.showerror("错误", f"加载配置文件失败: {e}")
            return self.default_config.copy()
    
    def save_config(self):
        """保存配置文件"""
        try:
            # 确保目录存在
            self.config_file.parent.mkdir(parents=True, exist_ok=True)
            
            with open(self.config_file, 'w', encoding='utf-8') as f:
                json.dump(self.config, f, indent=2, ensure_ascii=False)
            
            messagebox.showinfo("成功", "配置保存成功")
            return True
        except Exception as e:
            messagebox.showerror("错误", f"保存配置文件失败: {e}")
            return False
    
    def create_widgets(self):
        """创建界面组件"""
        # 创建主框架
        main_frame = ttk.Frame(self.root, padding="10")
        main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        # 配置网格权重
        self.root.columnconfigure(0, weight=1)
        self.root.rowconfigure(0, weight=1)
        main_frame.columnconfigure(1, weight=1)
        
        # 创建选项卡
        notebook = ttk.Notebook(main_frame)
        notebook.grid(row=0, column=0, columnspan=2, sticky=(tk.W, tk.E, tk.N, tk.S), pady=(0, 10))
        main_frame.rowconfigure(0, weight=1)
        
        # 服务管理选项卡
        self.create_service_tab(notebook)
        
        # 配置管理选项卡
        self.create_config_tab(notebook)
        
        # 底部按钮
        button_frame = ttk.Frame(main_frame)
        button_frame.grid(row=1, column=0, columnspan=2, sticky=(tk.W, tk.E))
        
        ttk.Button(button_frame, text="刷新状态", command=self.update_service_status).pack(side=tk.LEFT, padx=(0, 5))
        ttk.Button(button_frame, text="保存配置", command=self.save_config).pack(side=tk.LEFT, padx=(0, 5))
        ttk.Button(button_frame, text="退出", command=self.root.quit).pack(side=tk.RIGHT)
    
    def create_service_tab(self, notebook):
        """创建服务管理选项卡"""
        service_frame = ttk.Frame(notebook, padding="10")
        notebook.add(service_frame, text="服务管理")
        
        # 服务状态显示
        status_frame = ttk.LabelFrame(service_frame, text="服务状态", padding="10")
        status_frame.grid(row=0, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=(0, 10))
        service_frame.columnconfigure(0, weight=1)
        
        ttk.Label(status_frame, text="服务名称:").grid(row=0, column=0, sticky=tk.W, padx=(0, 10))
        self.service_name_label = ttk.Label(status_frame, text=self.service_manager.display_name)
        self.service_name_label.grid(row=0, column=1, sticky=tk.W)
        
        ttk.Label(status_frame, text="服务状态:").grid(row=1, column=0, sticky=tk.W, padx=(0, 10))
        self.service_status_label = ttk.Label(status_frame, text="检查中...")
        self.service_status_label.grid(row=1, column=1, sticky=tk.W)
        
        ttk.Label(status_frame, text="管理员权限:").grid(row=2, column=0, sticky=tk.W, padx=(0, 10))
        admin_status = "是" if self.service_manager.is_admin() else "否"
        self.admin_status_label = ttk.Label(status_frame, text=admin_status)
        self.admin_status_label.grid(row=2, column=1, sticky=tk.W)
        
        # 服务操作按钮
        action_frame = ttk.LabelFrame(service_frame, text="服务操作", padding="10")
        action_frame.grid(row=1, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=(0, 10))
        
        # 按钮网格布局
        ttk.Button(action_frame, text="安装服务", command=self.install_service).grid(row=0, column=0, padx=(0, 5), pady=(0, 5))
        ttk.Button(action_frame, text="卸载服务", command=self.uninstall_service).grid(row=0, column=1, padx=(0, 5), pady=(0, 5))
        ttk.Button(action_frame, text="启动服务", command=self.start_service).grid(row=1, column=0, padx=(0, 5), pady=(0, 5))
        ttk.Button(action_frame, text="停止服务", command=self.stop_service).grid(row=1, column=1, padx=(0, 5), pady=(0, 5))
    
    def create_config_tab(self, notebook):
        """创建配置管理选项卡"""
        config_frame = ttk.Frame(notebook, padding="10")
        notebook.add(config_frame, text="系统配置")
        
        # API服务器配置
        api_frame = ttk.LabelFrame(config_frame, text="API服务器配置", padding="10")
        api_frame.grid(row=0, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=(0, 10))
        config_frame.columnconfigure(0, weight=1)
        
        ttk.Label(api_frame, text="主机地址:").grid(row=0, column=0, sticky=tk.W, padx=(0, 10))
        self.api_host_var = tk.StringVar(value=self.config.get("api_host", "127.0.0.1"))
        ttk.Entry(api_frame, textvariable=self.api_host_var).grid(row=0, column=1, sticky=(tk.W, tk.E), padx=(0, 10))
        
        ttk.Label(api_frame, text="端口:").grid(row=1, column=0, sticky=tk.W, padx=(0, 10))
        self.api_port_var = tk.StringVar(value=str(self.config.get("api_port", 58501)))
        ttk.Entry(api_frame, textvariable=self.api_port_var).grid(row=1, column=1, sticky=(tk.W, tk.E), padx=(0, 10))
        
        # 跨域配置
        ttk.Label(api_frame, text="跨域源:").grid(row=2, column=0, sticky=tk.W, padx=(0, 10))
        cors_origins = self.config.get("cors_origins", ["*"])
        cors_text = ", ".join(cors_origins) if isinstance(cors_origins, list) else str(cors_origins)
        self.cors_origins_var = tk.StringVar(value=cors_text)
        cors_entry = ttk.Entry(api_frame, textvariable=self.cors_origins_var)
        cors_entry.grid(row=2, column=1, sticky=(tk.W, tk.E), padx=(0, 10))
        
        # 跨域配置说明
        cors_help = ttk.Label(api_frame, text="多个源用逗号分隔，* 表示允许所有源", font=("TkDefaultFont", 8))
        cors_help.grid(row=3, column=1, sticky=tk.W, padx=(0, 10))
        
        api_frame.columnconfigure(1, weight=1)
        
        # 服务配置
        service_config_frame = ttk.LabelFrame(config_frame, text="服务配置", padding="10")
        service_config_frame.grid(row=1, column=0, columnspan=2, sticky=(tk.W, tk.E), pady=(10, 0))
        
        ttk.Label(service_config_frame, text="启动类型:").grid(row=0, column=0, sticky=tk.W, padx=(0, 10))
        self.startup_type_var = tk.StringVar(value=self.config.get("service_startup_type", "auto"))
        startup_combo = ttk.Combobox(service_config_frame, textvariable=self.startup_type_var, 
                                   values=["auto", "manual", "disabled"], state="readonly")
        startup_combo.grid(row=0, column=1, sticky=(tk.W, tk.E), padx=(0, 10))
        
        # 启动类型说明
        startup_descriptions = {
            "auto": "自动 - 开机自启动",
            "manual": "手动 - 需要手动启动", 
            "disabled": "禁用 - 无法启动"
        }
        self.startup_desc_label = ttk.Label(service_config_frame, 
                                          text=startup_descriptions.get(self.startup_type_var.get(), ""))
        self.startup_desc_label.grid(row=0, column=2, sticky=tk.W, padx=(10, 0))
        
        service_config_frame.columnconfigure(1, weight=1)
        
        # 绑定配置变更事件
        for var in [self.api_host_var, self.api_port_var, self.cors_origins_var, self.startup_type_var]:
            var.trace('w', self.on_config_changed)
        
        # 启动类型变更时更新说明
        def update_startup_desc(*args):
            desc = startup_descriptions.get(self.startup_type_var.get(), "")
            self.startup_desc_label.config(text=desc)
        
        self.startup_type_var.trace('w', update_startup_desc)
    
    def on_config_changed(self, *args):
        """配置变更事件"""
        try:
            self.config["api_host"] = self.api_host_var.get()
            self.config["api_port"] = int(self.api_port_var.get())
            self.config["service_startup_type"] = self.startup_type_var.get()
            
            # 处理跨域配置
            cors_text = self.cors_origins_var.get().strip()
            if cors_text:
                # 分割并清理跨域源列表
                cors_origins = [origin.strip() for origin in cors_text.split(",") if origin.strip()]
                self.config["cors_origins"] = cors_origins if cors_origins else ["*"]
            else:
                self.config["cors_origins"] = ["*"]
                
        except ValueError:
            pass  # 忽略无效输入
    
    def _detect_deployment_mode(self):
        """检测部署模式"""
        return path_manager.deployment_mode
    
    def _build_service_path(self):
        """构建服务路径，根据部署环境自动选择"""
        try:
            if self.deployment_mode == "exe":
                # 打包后的exe模式
                return self._build_exe_service_path()
            elif self.deployment_mode == "venv":
                # 虚拟环境模式
                return self._build_venv_service_path()
            else:
                # 普通Python环境模式
                return self._build_python_service_path()
        except Exception as e:
            return None, f"构建服务路径失败: {str(e)}"
    
    def _build_exe_service_path(self):
        """构建exe模式的服务路径"""
        # 获取当前exe文件所在目录
        if getattr(sys, 'frozen', False):
            # 打包后的exe环境 - exe文件所在目录
            current_dir = Path(sys.executable).parent
        else:
            # 开发环境 - 项目根目录
            current_dir = path_manager.app_dir
        
        exe_candidates = [
            "wms_service.exe",
            "wms_sample.exe", 
            "main.exe",
            "wms_simple.exe"
        ]
        
        # 优先在当前目录查找（部署包内的exe文件）
        for exe_name in exe_candidates:
            exe_path = current_dir / exe_name
            if exe_path.exists():
                # 确保不是service_config_manager.exe本身
                if exe_path.name != "service_config_manager.exe":
                    # 使用resolve()确保路径格式正确，并转换为字符串
                    return str(exe_path.resolve()), None
        
        # 如果当前目录没找到，且不是部署包环境，才搜索其他目录
        if 'deployments' not in str(current_dir):
            # 定义搜索目录（按优先级排序）
            search_dirs = [
                current_dir.parent,          # 上级目录  
                current_dir.parent.parent,   # 上上级目录
                Path.cwd(),                  # 当前工作目录
                Path.cwd().parent,           # 当前工作目录的上级
            ]
            
            for search_dir in search_dirs:
                if not search_dir.exists():
                    continue
                    
                for exe_name in exe_candidates:
                    exe_path = search_dir / exe_name
                    if exe_path.exists():
                        # 确保不是service_config_manager.exe本身
                        if exe_path.name != "service_config_manager.exe":
                            # 使用resolve()确保路径格式正确，并转换为字符串
                            return str(exe_path.resolve()), None
        
        # 如果没找到exe文件，在打包环境中不应该依赖Python解释器
        if getattr(sys, 'frozen', False):
            # 打包环境：只查找exe文件，不使用Python脚本
            return None, "未找到WMS服务可执行文件。请确保WMS主程序已正确部署在同级或上级目录中。\n支持的文件名: wms_service.exe, wms_sample.exe, main.exe, wms_simple.exe"
        
        # 开发环境：可以查找Python脚本并使用Python解释器运行
        script_candidates = [
            "wms_service.py",
            "main_server.py", 
            "main.py"
        ]
        
        for search_dir in search_dirs:
            if not search_dir.exists():
                continue
                
            for script_name in script_candidates:
                script_path = search_dir / script_name
                if script_path.exists():
                    # 在开发环境中使用当前Python解释器
                    python_exe = sys.executable
                    if os.path.exists(python_exe):
                        return f'"{python_exe}" "{script_path}"', None
        
        return None, "未找到WMS服务文件。请确保WMS主程序已正确部署。"
    
    def _build_venv_service_path(self):
        """构建虚拟环境模式的服务路径"""
        # 尝试多个可能的虚拟环境路径
        venv_candidates = [
            Path(r"D:\python\wms_env\Scripts\python.exe"),  # 指定的虚拟环境
            Path(sys.executable),  # 当前Python解释器
            Path(sys.prefix) / "Scripts" / "python.exe",  # 当前环境的python
        ]
        
        service_script = path_manager.app_dir / "wms_service.py"
        
        # 检查服务脚本是否存在
        if not service_script.exists():
            return None, f"服务脚本不存在: {service_script}"
        
        # 查找可用的Python解释器
        for python_exe in venv_candidates:
            if python_exe.exists():
                return f'"{python_exe}" "{service_script}"', None
        
        return None, "未找到可用的Python解释器"
    
    def _build_python_service_path(self):
        """构建普通Python环境的服务路径"""
        python_exe = sys.executable
        service_script = path_manager.app_dir / "wms_service.py"
        
        if not os.path.exists(python_exe):
            return None, f"Python解释器不存在: {python_exe}"
        
        if not service_script.exists():
            return None, f"服务脚本不存在: {service_script}"
        
        return f'"{python_exe}" "{service_script}"', None
    
    def update_service_status(self):
        """更新服务状态"""
        def update():
            try:
                status = self.service_manager.get_service_status()
                if status["success"]:
                    self.service_status_label.config(text=status["status_text"])
                else:
                    self.service_status_label.config(text="服务未安装")
            except Exception as e:
                self.service_status_label.config(text=f"状态检查失败: {e}")
        
        threading.Thread(target=update, daemon=True).start()
    
    def install_service(self):
        """安装服务"""
        def install():
            try:
                # 自动检测运行环境并构建服务路径
                service_path, error_msg = self._build_service_path()
                if not service_path:
                    messagebox.showerror("错误", error_msg)
                    return
                
                startup_type = self.config.get("service_startup_type", "manual")
                
                print(f"安装服务路径: {service_path}")
                result = self.service_manager.install_service(service_path, startup_type)
                
                if result["success"]:
                    messagebox.showinfo("成功", result["message"])
                else:
                    messagebox.showerror("错误", result["message"])
                
                self.update_service_status()
            except Exception as e:
                messagebox.showerror("错误", f"安装服务时发生错误: {e}")
        
        threading.Thread(target=install, daemon=True).start()
    
    def uninstall_service(self):
        """卸载服务"""
        if messagebox.askyesno("确认", "确定要卸载WMS服务吗？"):
            def uninstall():
                try:
                    result = self.service_manager.uninstall_service()
                    
                    if result["success"]:
                        messagebox.showinfo("成功", result["message"])
                    else:
                        messagebox.showerror("错误", result["message"])
                    
                    self.update_service_status()
                except Exception as e:
                    messagebox.showerror("错误", f"卸载服务时发生错误: {e}")
            
            threading.Thread(target=uninstall, daemon=True).start()
    
    def start_service(self):
        """启动服务"""
        def start():
            try:
                result = self.service_manager.start_service()
                
                if result["success"]:
                    messagebox.showinfo("成功", result["message"])
                else:
                    messagebox.showerror("错误", result["message"])
                
                self.update_service_status()
            except Exception as e:
                messagebox.showerror("错误", f"启动服务时发生错误: {e}")
        
        threading.Thread(target=start, daemon=True).start()
    
    def stop_service(self):
        """停止服务"""
        def stop():
            try:
                result = self.service_manager.stop_service()
                
                if result["success"]:
                    messagebox.showinfo("成功", result["message"])
                else:
                    messagebox.showerror("错误", result["message"])
                
                self.update_service_status()
            except Exception as e:
                messagebox.showerror("错误", f"停止服务时发生错误: {e}")
        
        threading.Thread(target=stop, daemon=True).start()
    
    def run(self):
        """运行GUI"""
        self.root.mainloop()


def main():
    """主函数"""
    app = ServiceConfigManager()
    app.run()


if __name__ == '__main__':
    main() 